<?php
class Category extends LilcartAppModel {

	var $name = 'Category';
	var $validate = array(
		'count' => array('numeric')
	);
	var $actsAs = array(
		'Tree', 
		'Containable', 
		'Translate' => array('title'=>'Title', 'descript'=>'Descript')
	);
	var $belongsTo = array(
		'Parent' => array(
			'className' => 'Lilcart.Category',
			'foreignKey' => 'parent_id',
		),
		'CategoriesItem'=>array(
			'className' => 'Lilcart.CategoriesItem',
			'foreignKey' => 'id',
		)
	);

/**
 * Callback function
 */
	function beforeSave() {
		if (empty($this->data['Category']['slug']) && 
			!empty($this->data['Category']['title']) && 
			is_string($this->data['Category']['title'])) 
		{
			$this->data['Category']['slug'] = strtolower(Inflector::slug(
				mb_convert_encoding($this->data['Category']['title'], 'ASCII'), '-'));
			if ($this->hasAny(array(
				'Category.slug'=>$this->data['Category']['slug'], 
				'NOT'=>array('Category.id'=>$this->id)))) 
			{
				$i = 2;
				while ($this->hasAny(array(
					'Category.slug'=>$this->data['Category']['slug'].'-'.$i, 
					'NOT'=>array('Category.id'=>$this->id)))) 
				{
					$i++;
					if ($i>100) break;
				}
				$this->data['Category']['slug'] .= '-'.$i;
			}
		}
		return true;
	}

/**
 * Returns category_id for specified path.
 * Path parameter can be string or array: 
 * - string - e.g. /parentslug1/parentslug2
 * - array - e.g. array('parentslug1', 'parentslug2')
 *
 * @param mixed $path Node path
 * @return int category_id for given path
 * @access public
 */
	function lookup($path=null) {
		if (is_string($path)) {
			$path = explode('/', $path);
		}
		$category_id = null;
		foreach ((array)$path as $slug) {
			$category_id = $this->field('id', array('parent_id'=>$category_id, 'slug'=>$slug));
		}
		return $category_id;
	}

/**
 * Returns child categories that have items which also belong to second set of categories
 *
 * @param int Parent category id
 * @param array List of Categories in which items must also be in
 * @return array Categories that meet specified criterio
 * @access public
 */
	function childrenWithItems($id, $additional=null, $direct=false) {
		// first get all children categories
		$categories = $this->children($id, $direct);
		
		$additionals = array();
		foreach ((array)$additional as $additional_id) {
			$ad_children = $this->children($additional_id, false, array('id'));
			$additionals[$additional_id] = array_merge(array($additional_id), Set::extract($ad_children, '{n}.Category.id'));
		}
		foreach ($categories as $k=>$category) {
			$i = 0; 
			$this->CategoriesItem->primaryKey = 'item_id';
			foreach ($additionals as $additionals_one) {
				// mambo jumbo
				
				$this->CategoriesItem->bindModel(array('hasOne' => array(
					'Ad'.$i => array(
						'className' => 'Lilcart.CategoriesItem',
						'conditions' => array('Ad'.$i.'.category_id'=>$additionals_one),
						'foreignKey' => 'item_id',
						'type' => 'INNER'
					)
				)));
			}
			$data = $this->CategoriesItem->find('all', array('conditions'=>array('CategoriesItem.category_id'=>$category['Category']['id']), 'fields'=>array('COUNT(DISTINCT CategoriesItem.item_id) AS item_count')));
			if (empty($data[0][0]['item_count'])) {
				unset($categories[$k]);
			} else {
				$categories[$k]['items_count'] = $data[0][0]['item_count'];
			}
			$this->CategoriesItem->primaryKey = 'id';
		}
		return $categories;
	}

}
?>